home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / GDIMETA.PAK / PALCTRL.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  24KB  |  855 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE:   palctrl.c
  9. //
  10. //  PURPOSE:  Implement the window procedure for the palette control
  11. //            window.
  12. //
  13. //  FUNCTIONS:
  14. //    RegisterPalCtrlClass    - Registers the PalCtrl window class.
  15. //    PalCtrlProc             - Processes messages for the main window.
  16. //    MsgPalCtrlCommand       - Handle the WM_COMMAND messages for the window.
  17. //    MsgPalCtrlPaint         - Handles the WM_PAINT messages.
  18. //    MsgPalCtrlLButtonDown   - Handles the WM_LBUTTONDOWN messages.
  19. //    MsgPalCtrlLButtonDblClk - Handles the WM_LBUTTONDBLCLK messages.
  20. //    MsgPalCtrlGetDlgCode    - Handles the WM_GETDLGCODE message.
  21. //    MsgPalCtrlKeyDown       - Handles the WMKEYDOWN messages.
  22. //    MsgPalCtrlDestroy       - Handles the WM_DESTROY message by calling 
  23. //                              PostQuitMessage().
  24. //    MsgPalCtrlGetCurSel     - Handles the PCM_GETCURSEL messages.
  25. //    MsgPalCtrlSetCurSel     - Handles the PCM_SETCURSEL messages.
  26. //    HighlightSquare         - Highlights a color square on the PalCtrl.
  27. //    UnHighlightSquare       - Unhighlights a color square on the PalCtrl.
  28. //    SetPalCtrlPalette       - Sets the palette to be displayed in the
  29. //                              PalCtrl window.
  30. //
  31. //  COMMENTS:
  32. //
  33.  
  34. #include <windows.h>            // required for all Windows applications
  35. #include <windowsx.h>
  36. #include <commctrl.h>
  37. #include "globals.h"            // prototypes specific to this application
  38. #include "palette.h"
  39. #include "palctrl.h"
  40.  
  41.  
  42. // globals
  43. PALINFO palinfo;
  44.  
  45.  
  46. // Palette control message table definition.
  47. MSD rgmsdPalCtrl[] =
  48. {
  49.     {WM_CREATE,        MsgPalCtrlCreate},
  50.     {WM_PAINT,         MsgPalCtrlPaint},
  51.     {WM_LBUTTONDOWN,   MsgPalCtrlLButtonDown},
  52.     {WM_LBUTTONDBLCLK, MsgPalCtrlLButtonDblClk},
  53.     {WM_DESTROY,       MsgPalCtrlDestroy},
  54.     {WM_GETDLGCODE,    MsgPalCtrlGetDlgCode},
  55.     {WM_KEYDOWN,       MsgPalCtrlKeyDown},
  56.  
  57.     // PalCtrl interface messages
  58.     {PCM_GETCURSEL,    MsgPalCtrlGetCurSel},
  59.     {PCM_SETCURSEL,    MsgPalCtrlSetCurSel}
  60. };
  61.  
  62. MSDI msdiPalCtrl =
  63. {
  64.     sizeof(rgmsdPalCtrl) / sizeof(MSD),
  65.     rgmsdPalCtrl,
  66.     edwpWindow
  67. };
  68.  
  69.  
  70. //
  71. //  FUNCTION: RegisterPalCtrlClass(HINSTANCE)
  72. //
  73. //  PURPOSE:  Registers the palette control window class.
  74. //
  75. //  PARAMETERS:
  76. //
  77. //    hInstance - instance that owns this class
  78. //
  79. //  RETURN VALUE:
  80. //
  81. //    TRUE for success, FALSE otherwise
  82. //
  83. //  COMMENTS:
  84. //
  85.  
  86. BOOL RegisterPalCtrlClass(HINSTANCE hInstance)
  87. {
  88.     WNDCLASS wc;
  89.  
  90.     // Fill in window class structure with parameters that describe the
  91.     // palette control window.
  92.  
  93.     wc.style         = CS_DBLCLKS;              // Class style(s).
  94.     wc.lpfnWndProc   = (WNDPROC)PalCtrlProc;    // Window Procedure
  95.     wc.cbClsExtra    = 0;                       // No per-class extra data.
  96.     wc.cbWndExtra    = PAL_CBWNDEXTRA;          // Per-window extra data.
  97.     wc.hInstance     = hInstance;               // Owner of this class
  98.     wc.hIcon         = NULL;                    // Icon name from .RC
  99.     wc.hCursor       = LoadCursor(NULL, IDC_ARROW); // Cursor
  100.     wc.hbrBackground = GetStockObject(NULL_BRUSH); // Default color
  101.     wc.lpszMenuName  = NULL;                    // Menu name from .RC
  102.     wc.lpszClassName = "PalCtrlClass";          // Name to register as
  103.  
  104.     // Register the window class
  105.     return RegisterClass(&wc);
  106. }
  107.  
  108.  
  109. //
  110. //  FUNCTION: PalCtrlProc(HWND, UINT, WPARAM, LPARAM)
  111. //
  112. //  PURPOSE:  Processes messages for the main window.
  113. //
  114. //  PARAMETERS:
  115. //    hwnd     - window handle
  116. //    uMessage - message number
  117. //    wparam   - additional information (dependant on message number)
  118. //    lparam   - additional information (dependant on message number)
  119. //
  120. //  RETURN VALUE:
  121. //    The return value depends on the message number.  If the message
  122. //    is implemented in the message dispatch table, the return value is
  123. //    the value returned by the message handling function.  Otherwise,
  124. //    the return value is the value returned by the default window procedure.
  125. //
  126. //  COMMENTS:
  127. //    Call the DispMessage() function with the main window's message dispatch
  128. //    information (msdiPalCtrl) and the message specific information.
  129. //
  130.  
  131. LRESULT CALLBACK PalCtrlProc(HWND   hwnd, 
  132.                              UINT   uMessage, 
  133.                              WPARAM wparam, 
  134.                              LPARAM lparam)
  135. {
  136.     return DispMessage(&msdiPalCtrl, hwnd, uMessage, wparam, lparam);
  137. }
  138.  
  139.  
  140. //
  141. //  FUNCTION: MsgPalCtrlCreate(HWND, UINT, WPARAM, LPARAM)
  142. //
  143. //  PURPOSE: 
  144. //
  145. //  PARAMETERS:
  146. //
  147. //    hwnd      - Window handle  (Unused)
  148. //    uMessage  - Message number (Unused)
  149. //    wparam    - Extra data     (Unused)
  150. //    lparam    - Extra data     (Unused)
  151. //
  152. //  RETURN VALUE:
  153. //
  154. //    Always returns 0 - Message handled
  155. //
  156. //  COMMENTS:
  157. //
  158.  
  159. #pragma argsused
  160. LRESULT MsgPalCtrlCreate(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  161. {
  162.     HANDLE hPalCtrlInfo;
  163.  
  164.     hPalCtrlInfo = GlobalAlloc(GHND, sizeof(PALCTRLINFO));
  165.     if (hPalCtrlInfo)
  166.     {
  167.         RECT          rect;
  168.         LPPALCTRLINFO lpPalCtrlInfo;
  169.  
  170.         GetClientRect(hwnd, &rect);
  171.  
  172.         lpPalCtrlInfo              = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  173.         lpPalCtrlInfo->hPal        = NULL;
  174.         lpPalCtrlInfo->nEntries    = 0;
  175.         lpPalCtrlInfo->nRows       = 16;
  176.         lpPalCtrlInfo->nCols       = 16;
  177.         lpPalCtrlInfo->cxSquare    = (rect.right - rect.left) / 16;
  178.         lpPalCtrlInfo->cySquare    = (rect.bottom - rect.top) / 16;
  179.         lpPalCtrlInfo->nEntry      = 0;
  180.  
  181.         GlobalUnlock(hPalCtrlInfo);
  182.     }
  183.  
  184.     SetWindowLong(hwnd, WL_PAL_HPALCTRLINFO, (LONG)hPalCtrlInfo);
  185.  
  186.     SetPalCtrlPalette(hwnd, GetSystemPalette());
  187.  
  188.     // notify parent
  189.     PostMessage(GetParent(hwnd),
  190.                 WM_COMMAND,
  191.                 MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID), PCN_CHANGE),
  192.                 (LPARAM)hwnd);
  193.  
  194.     return 0;
  195. }
  196.  
  197.  
  198. //
  199. //  FUNCTION: MsgPalCtrlPaint(HWND, UINT, WPARAM, LPARAM)
  200. //
  201. //  PURPOSE: 
  202. //
  203. //  PARAMETERS:
  204. //
  205. //    hwnd      - Window handle  (Unused)
  206. //    uMessage  - Message number (Unused)
  207. //    wparam    - Extra data     (Unused)
  208. //    lparam    - Extra data     (Unused)
  209. //
  210. //  RETURN VALUE:
  211. //
  212. //    Always returns 0 - Message handled
  213. //
  214. //  COMMENTS:
  215. //
  216.  
  217. #pragma argsused
  218. LRESULT MsgPalCtrlPaint(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  219. {
  220.      RECT          rect;
  221.      HDC           hDC;
  222.      PAINTSTRUCT   ps;
  223.     int           nCols;
  224.      int           nColors, i;
  225.      int           cxSquare, cySquare;
  226.      HPALETTE      hPal, hOldPal;
  227.     HANDLE        hPalCtrlInfo;
  228.     LPPALCTRLINFO lpPalCtrlInfo;
  229.     int           nCurrent;
  230.  
  231.     // First do some setup.
  232.  
  233.     GetClientRect(hwnd, &rect);
  234.  
  235.     hDC      = BeginPaint(hwnd, &ps);
  236.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  237.  
  238.     if (!hPalCtrlInfo)
  239.         goto ENDPAINT;
  240.  
  241.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  242.     hPal          = lpPalCtrlInfo->hPal;
  243.     nColors       = lpPalCtrlInfo->nEntries;
  244.     cxSquare      = lpPalCtrlInfo->cxSquare;
  245.     cySquare      = lpPalCtrlInfo->cySquare;
  246.      nCurrent      = lpPalCtrlInfo->nEntry;
  247.     nCols         = lpPalCtrlInfo->nCols;
  248.     GlobalUnlock(hPalCtrlInfo);
  249.  
  250.     // Let's paint -- first realize the palette.  Note that
  251.     //  we ALWAYS realize the palette as if it were a background
  252.     //  palette (i.e. the last parm is TRUE).  We do this, since
  253.     //  we will already be the foreground palette if we are
  254.     //  supposed to be (because we handle the WM_QUERYNEWPALETTE
  255.     //  message).
  256.     if (hPal)
  257.         hOldPal = SelectPalette(hDC, hPal, TRUE);
  258.      else
  259.         goto ENDPAINT;
  260.  
  261.     RealizePalette(hDC);
  262.  
  263.     // Go through the palette displaying each color
  264.     //  as a rectangle.
  265.     for (i = 0;  i < nColors;  i++)
  266.     {
  267.         HBRUSH hBrush, hOldBrush;
  268.  
  269.         hBrush = CreateSolidBrush(PALETTEINDEX(i));
  270.           if (hBrush)
  271.         {
  272.             POINT pt;
  273.  
  274.             hOldBrush = SelectObject(hDC, hBrush);
  275.  
  276.             pt.x = (i % nCols) * cxSquare;
  277.             pt.y = (i / nCols) * cySquare;
  278.  
  279.             Rectangle(hDC,
  280.                       pt.x,
  281.                       pt.y,
  282.                              pt.x + cxSquare,
  283.                       pt.y + cySquare);
  284.  
  285.             SelectObject(hDC, hOldBrush);
  286.             DeleteObject(hBrush);
  287.         }
  288.     }
  289.  
  290.     // Highlight the currently selected palette square
  291.     HighlightSquare(hDC, 
  292.                     hPal, 
  293.                     nCurrent,
  294.                           cxSquare,
  295.                     cySquare, 
  296.                     nCols,
  297.                     nColors);
  298.  
  299.     // Clean up.
  300.     if (hOldPal)
  301.         SelectPalette(hDC, hOldPal, FALSE);
  302.  
  303. ENDPAINT:
  304.     EndPaint(hwnd, &ps);
  305.     
  306.      return 0;
  307. }
  308.  
  309.  
  310. //
  311. //  FUNCTION: MsgPalCtrlLButtonDown(HWND, UINT, WPARAM, LPARAM)
  312. //
  313. //  PURPOSE:  Process WM_LBUTTONDOWN messages by performing hit-testing
  314. //            on the color grid to see which color is selected by the user.
  315. //
  316. //  PARAMETERS:
  317. //
  318. //    hwnd      - Window handle  (Unused)
  319. //    uMessage  - Message number (Unused)
  320. //    wparam    - Extra data     (Unused)
  321. //    lparam    - Extra data     (Unused)
  322. //
  323. //  RETURN VALUE:
  324. //
  325. //    Always returns 0 - Message handled
  326. //
  327. //  COMMENTS:
  328. //
  329.  
  330. #pragma argsused
  331. LRESULT MsgPalCtrlLButtonDown(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  332. {
  333.     HDC           hDC;
  334.     HANDLE        hPalCtrlInfo;
  335.     LPPALCTRLINFO lpPalCtrlInfo;
  336.     int           nRow, nCol;
  337.  
  338.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  339.     if (!hPalCtrlInfo)
  340.         return 0;
  341.  
  342.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  343.     nRow          = (HIWORD(lparam)) / lpPalCtrlInfo->cySquare;
  344.      nCol          = LOWORD(lparam) / lpPalCtrlInfo->cxSquare;
  345.     hDC           = GetDC(hwnd);
  346.  
  347.     // Determine which entry is the new highlighted entry.
  348.     // Since our actual palette grid may not fill the entire
  349.     // control, check that we're really clicking in the palette
  350.     // gris and not just in the control client area...
  351.     if (nCol < 16)
  352.         if ((nRow * lpPalCtrlInfo->nCols + nCol) < lpPalCtrlInfo->nEntries)
  353.         {
  354.             UnHighlightSquare(hDC, 
  355.                               lpPalCtrlInfo->nEntry, 
  356.                                         lpPalCtrlInfo->cxSquare,
  357.                               lpPalCtrlInfo->cySquare,
  358.                               lpPalCtrlInfo->nCols);
  359.  
  360.             lpPalCtrlInfo->nEntry = nRow * lpPalCtrlInfo->nCols + nCol;
  361.         
  362.             HighlightSquare(hDC,
  363.                             lpPalCtrlInfo->hPal, 
  364.                             lpPalCtrlInfo->nEntry,
  365.                             lpPalCtrlInfo->cxSquare, 
  366.                             lpPalCtrlInfo->cySquare, 
  367.                             lpPalCtrlInfo->nCols,
  368.                                      lpPalCtrlInfo->nEntries);
  369.         
  370.             // notify parent
  371.             PostMessage(GetParent(hwnd),
  372.                         WM_COMMAND,
  373.                         MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID),
  374.                                    PCN_CHANGE),
  375.                         (LPARAM)hwnd);
  376.         }
  377.  
  378.     ReleaseDC(hwnd, hDC);
  379.     GlobalUnlock(hPalCtrlInfo);
  380.  
  381.     return 0;
  382. }
  383.  
  384.  
  385. //
  386. //  FUNCTION: MsgPalCtrlLButtonDblClk(HWND, UINT, WPARAM, LPARAM)
  387. //
  388. //  PURPOSE:  Process WM_LBUTTONDBLCLK messages by sending WM_COMMAND IDOK
  389. //            to the parent window.
  390. //
  391. //  PARAMETERS:
  392. //
  393. //    hwnd      - Window handle  (Unused)
  394. //    uMessage  - Message number (Unused)
  395. //    wparam    - Extra data     (Unused)
  396. //    lparam    - Extra data     (Unused)
  397. //
  398. //  RETURN VALUE:
  399. //
  400. //    Always returns 0 - Message handled
  401. //
  402. //  COMMENTS:
  403. //
  404.  
  405. #pragma argsused
  406. LRESULT MsgPalCtrlLButtonDblClk(HWND   hwnd,
  407.                                 UINT   uMessage,
  408.                                 WPARAM wparam,
  409.                                 LPARAM lparam)
  410. {
  411.     // send IDOK to parent window
  412.     PostMessage(GetParent(hwnd),
  413.                 WM_COMMAND,
  414.                 MAKEWPARAM(IDOK, (WORD)GetWindowLong(hwnd, GWL_ID)),
  415.                      (LPARAM)hwnd);
  416.  
  417.     return 0;
  418. }
  419.  
  420.  
  421. //
  422. //  FUNCTION: MsgPalCtrlGetDlgCode(HWND, UINT, WPARAM, LPARAM)
  423. //
  424. //  PURPOSE:  Process WM_GETDLGCODE in order for PalCtrl to receive input
  425. //            for the arrow keys.
  426. //
  427. //  PARAMETERS:
  428. //
  429. //    hwnd      - Window handle  (Unused)
  430. //    uMessage  - Message number (Unused)
  431. //    wparam    - Extra data     (Unused)
  432. //    lparam    - Extra data     (Unused)
  433. //
  434. //  RETURN VALUE:
  435. //
  436. //    Returns DLGC_WANTARROWS
  437. //
  438. //  COMMENTS:
  439. //
  440.  
  441. #pragma argsused
  442. LRESULT MsgPalCtrlGetDlgCode(HWND   hwnd,
  443.                                       UINT   uMessage,
  444.                                       WPARAM wparam,
  445.                              LPARAM lparam)
  446. {
  447.     return DLGC_WANTARROWS;
  448. }
  449.  
  450.  
  451. //
  452. //  FUNCTION: MsgPalCtrlKeyDown(HWND, UINT, WPARAM, LPARAM)
  453. //
  454. //  PURPOSE:  Process WM_KEYDOWN messages by changing the selected color
  455. //            accordingly.
  456. //
  457. //  PARAMETERS:
  458. //
  459. //    hwnd      - Window handle  (Unused)
  460. //    uMessage  - Message number (Unused)
  461. //    wparam    - Extra data     (Unused)
  462. //    lparam    - Extra data     (Unused)
  463. //
  464. //  RETURN VALUE:
  465. //
  466. //    Always returns 0 - Message handled
  467. //
  468. //  COMMENTS:
  469. //
  470.  
  471. #pragma argsused
  472. LRESULT MsgPalCtrlKeyDown(HWND   hwnd,
  473.                           UINT   uMessage,
  474.                           WPARAM wparam,
  475.                           LPARAM lparam)
  476. {
  477.     HDC           hDC;
  478.     HANDLE        hPalCtrlInfo;
  479.     LPPALCTRLINFO lpPalCtrlInfo;
  480.     int           nEntry, nMaxEntry;
  481.     int           nCol;
  482.  
  483.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  484.     if (!hPalCtrlInfo)
  485.         return 0;
  486.  
  487.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  488.     
  489.     nEntry    = lpPalCtrlInfo->nEntry;
  490.     nMaxEntry = lpPalCtrlInfo->nEntries - 1;
  491.     nCol      = lpPalCtrlInfo->nCols;
  492.  
  493.     switch (wparam)
  494.     {
  495.         case VK_LEFT:
  496.                 if ((nEntry - 1) <= 0)
  497.                 nEntry = 0;
  498.             else
  499.                 nEntry--;
  500.             goto UpdateSelection;
  501.  
  502.           case VK_RIGHT:
  503.                 if ((nEntry + 1) >= nMaxEntry)
  504.                      nEntry = nMaxEntry;
  505.                 else
  506.                      nEntry++;
  507.                 goto UpdateSelection;
  508.  
  509.           case VK_UP:
  510.                 if ((nEntry - nCol) >= 0)
  511.                      nEntry -= nCol;
  512.                 goto UpdateSelection;
  513.  
  514.           case VK_DOWN:
  515.                 if ((nEntry + nCol) <= nMaxEntry)
  516.                      nEntry += nCol;
  517.  
  518. UpdateSelection:
  519.                 if (nEntry != lpPalCtrlInfo->nEntry)
  520.                 {
  521.                      hDC = GetDC(hwnd);
  522.  
  523.                      UnHighlightSquare(hDC,
  524.                                              lpPalCtrlInfo->nEntry,
  525.                                              lpPalCtrlInfo->cxSquare,
  526.                                              lpPalCtrlInfo->cySquare,
  527.                                              lpPalCtrlInfo->nCols);
  528.  
  529.                      lpPalCtrlInfo->nEntry = nEntry;
  530.  
  531.                      HighlightSquare(hDC,
  532.                                           lpPalCtrlInfo->hPal,
  533.                                           lpPalCtrlInfo->nEntry,
  534.                                           lpPalCtrlInfo->cxSquare,
  535.                                           lpPalCtrlInfo->cySquare,
  536.                                           lpPalCtrlInfo->nCols,
  537.                                           lpPalCtrlInfo->nEntries);
  538.         
  539.                 // notify parent
  540.                 PostMessage(GetParent(hwnd),
  541.                             WM_COMMAND,
  542.                             MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID),
  543.                                        PCN_CHANGE),
  544.                             (LPARAM)hwnd);
  545.             
  546.                 ReleaseDC(hwnd, hDC);
  547.             }
  548.             break;
  549.  
  550.         default:
  551.             break;
  552.     }
  553.  
  554.     GlobalUnlock(hPalCtrlInfo);
  555.  
  556.     return 0;
  557. }
  558.  
  559.  
  560. //
  561. //  FUNCTION: MsgPalCtrlDestroy(HWND, UINT, WPARAM, LPARAM)
  562. //
  563. //  PURPOSE: Calls PostQuitMessage().
  564. //
  565. //  PARAMETERS:
  566. //
  567. //    hwnd      - Window handle  (Unused)
  568. //    uMessage  - Message number (Unused)
  569. //    wparam    - Extra data     (Unused)
  570. //    lparam    - Extra data     (Unused)
  571. //
  572. //  RETURN VALUE:
  573. //
  574. //    Always returns 0 - Message handled
  575. //
  576. //  COMMENTS:
  577. //
  578.  
  579. #pragma argsused
  580. LRESULT MsgPalCtrlDestroy(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  581. {
  582.      HANDLE    hPalCtrlInfo;
  583.      LPPALCTRLINFO lpPalCtrlInfo;
  584.  
  585.      hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  586.      if (!hPalCtrlInfo)
  587.           return 0;
  588.  
  589.      lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  590.  
  591.     if (lpPalCtrlInfo->hPal)
  592.         DeleteObject(lpPalCtrlInfo->hPal);
  593.  
  594.     GlobalUnlock(hPalCtrlInfo);
  595.     GlobalFree(hPalCtrlInfo);
  596.     SetWindowLong(hwnd, WL_PAL_HPALCTRLINFO, 0);
  597.     
  598.      return 0;
  599. }
  600.  
  601.  
  602. //
  603. //  FUNCTION: MsgPalCtrlGetCurSel(HWND, UINT, WPARAM, LPARAM)
  604. //
  605. //  PURPOSE: Fills in PALINFO structure with index and RGB values
  606. //
  607. //  PARAMETERS:
  608. //
  609. //    hwnd      - Window handle of PalCtrl
  610. //    uMessage  - Message number (Unused)
  611. //    wparam    - Extra data     (Unused)
  612. //    lparam    - Pointer to a PALINFO structure
  613. //
  614. //  RETURN VALUE:
  615. //
  616. //    Always returns 0 - Message handled
  617. //
  618. //  COMMENTS:
  619. //
  620.  
  621. #pragma argsused
  622. LRESULT MsgPalCtrlGetCurSel(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  623. {
  624.      HANDLE        hPalCtrlInfo;
  625.      LPPALCTRLINFO lpPalCtrlInfo;
  626.      HDC           hdc;
  627.     HPALETTE      hOldPal;
  628.     COLORREF      crColor;
  629.  
  630.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  631.     if (!hPalCtrlInfo)
  632.         return 0;
  633.     
  634.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  635.  
  636.     hdc     = GetDC(hwnd);
  637.     hOldPal = SelectPalette(hdc, lpPalCtrlInfo->hPal, TRUE);
  638.      RealizePalette(hdc);
  639.     crColor = GetNearestColor(hdc, PALETTEINDEX(lpPalCtrlInfo->nEntry));
  640.  
  641.     // fill in info
  642.     ((LPPALINFO)lparam)->index = lpPalCtrlInfo->nEntry;
  643.     ((LPPALINFO)lparam)->red   = GetRValue(crColor);
  644.     ((LPPALINFO)lparam)->green = GetGValue(crColor);
  645.     ((LPPALINFO)lparam)->blue  = GetBValue(crColor);
  646.  
  647.     SelectPalette(hdc, hOldPal, TRUE);
  648.     ReleaseDC(hwnd, hdc);
  649.     GlobalUnlock(hPalCtrlInfo);
  650.  
  651.     return 0;
  652. }
  653.  
  654.  
  655. //
  656. //  FUNCTION: MsgPalCtrlGetCurSel(HWND, UINT, WPARAM, LPARAM)
  657. //
  658. //  PURPOSE: Sets selected color for the PalCtrl
  659. //
  660. //  PARAMETERS:
  661. //
  662. //    hwnd      - Window handle  (Unused)
  663. //    uMessage  - Message number (Unused)
  664. //    wparam    - Extra data     (Unused)
  665. //    lparam    - Contains desired index to be selected
  666. //
  667. //  RETURN VALUE:
  668. //
  669. //    Always returns 0 - Message handled
  670. //
  671. //  COMMENTS:
  672. //
  673.  
  674. #pragma argsused
  675. LRESULT MsgPalCtrlSetCurSel(HWND hwnd, UINT uMessage, WPARAM wparam, LPARAM lparam)
  676. {
  677.     HANDLE        hPalCtrlInfo;
  678.     LPPALCTRLINFO lpPalCtrlInfo;
  679.     HDC           hDC;
  680.  
  681.     hPalCtrlInfo = (HANDLE)GetWindowLong(hwnd, WL_PAL_HPALCTRLINFO);
  682.     if (!hPalCtrlInfo)
  683.         return 0;
  684.     lpPalCtrlInfo = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  685.  
  686.     // store selected index
  687.     lpPalCtrlInfo->nEntry = (int)lparam;
  688.  
  689.     hDC = GetDC(hwnd);
  690.  
  691.     // Highlight the specified palette square
  692.     HighlightSquare(hDC,
  693.                     lpPalCtrlInfo->hPal,
  694.                     lpPalCtrlInfo->nEntry,
  695.                     lpPalCtrlInfo->cxSquare,
  696.                     lpPalCtrlInfo->cySquare,
  697.                           lpPalCtrlInfo->nCols,
  698.                     lpPalCtrlInfo->nEntries);
  699.  
  700.     ReleaseDC(hwnd, hDC);
  701.     
  702.     // notify parent so appropriate updating occurs
  703.     PostMessage(GetParent(hwnd),
  704.                 WM_COMMAND,
  705.                 MAKEWPARAM((WORD)GetWindowLong(hwnd, GWL_ID),
  706.                            PCN_CHANGE),
  707.                 (LPARAM)hwnd);
  708.  
  709.      GlobalUnlock(hPalCtrlInfo);
  710.  
  711.     return 0;
  712. }
  713.  
  714.  
  715. //
  716. //  FUNCTION: HighlightSquare(HDC, HPALETTE, int, int, int, int, int)
  717. //
  718. //  PURPOSE:  Highlight the currently selected palette entry and
  719. //            change the info bar to reflect it.
  720. //
  721. //  PARAMETERS:
  722. //    hDC       - DC where we want to highlight a pal. square.
  723. //    hPal      - Handle to the palette we're displaying info on.
  724. //    nEntry    - Entry to highlight.
  725. //    cxSquare  - Width a a palette square.
  726. //    cySquare  - Height of a palette square.
  727. //    nCols     - # of columns currently displayed in window.
  728. //    nColors   - # of colors in the palette.
  729. //
  730. //  RETURN VALUE:
  731. //    None.
  732. //
  733. //  COMMENTS:
  734. //
  735.  
  736. #pragma argsused
  737. void HighlightSquare(HDC hDC, 
  738.                             HPALETTE hPal,
  739.                             int nEntry,
  740.                      int cxSquare, 
  741.                      int cySquare, 
  742.                      int nCols,
  743.                      int nColors)
  744. {
  745.     RECT         rect;
  746.     HBRUSH       hBrush;
  747.     PALETTEENTRY pe;
  748.  
  749.     rect.left   = (nEntry % nCols) * cxSquare;
  750.     rect.top    = (nEntry / nCols) * cySquare;
  751.      rect.right  = rect.left + cxSquare;
  752.     rect.bottom = rect.top  + cySquare;
  753.     hBrush      = CreateHatchBrush(HS_BDIAGONAL,
  754.                                    GetSysColor(COLOR_HIGHLIGHT));
  755.  
  756.     FrameRect(hDC, &rect, hBrush);
  757.  
  758.     GetPaletteEntries(hPal, nEntry, 1, &pe);
  759.  
  760.     // If the palette entry we just got is just an index into the
  761.     //  system palette, get it's RGB value.
  762.  
  763.      if (pe.peFlags == PC_EXPLICIT)
  764.     {
  765.         COLORREF cref;
  766.         HPALETTE hOldPal;
  767.  
  768.         cref       = PALETTEINDEX((WORD)pe.peRed + (pe.peGreen << 4));
  769.         hOldPal    = SelectPalette(hDC, hPal, FALSE);
  770.         cref       = GetNearestColor(hDC, cref);
  771.         pe.peRed   = (BYTE)  (cref & 0x0000FF);
  772.         pe.peGreen = (BYTE) ((cref & 0x00FF00) >> 8);
  773.         pe.peBlue  = (BYTE) ((cref & 0xFF0000) >> 16);  
  774.  
  775.           SelectPalette(hDC, hOldPal, FALSE);
  776.     }
  777.  
  778.     DeleteObject(hBrush);
  779. }
  780.  
  781. //
  782. //  FUNCTION: UnHighlightSquare(HDC, int, int, int, int)
  783. //
  784. //  PURPOSE:  Un-highlight a palette entry.
  785. //
  786. //  PARAMETERS:
  787. //    hDC       - DC where we want to unhighlight a pal. square.
  788. //    nEntry    - Entry to highlight.
  789. //    cxSquare  - Width a a palette square.
  790. //    cySquare  - Height of a palette square.
  791. //    nCols     - # of columns currently displayed in window.
  792. //
  793. //  RETURN VALUE:
  794. //    None.
  795. //
  796. //  COMMENTS:
  797. //
  798.  
  799. void UnHighlightSquare(HDC hDC, 
  800.                        int nEntry, 
  801.                        int cxSquare, 
  802.                        int cySquare,
  803.                        int nCols)
  804. {
  805.     RECT rect;
  806.  
  807.     rect.left   = (nEntry % nCols) * cxSquare;
  808.     rect.top    = (nEntry / nCols) * cySquare;
  809.     rect.right  = rect.left + cxSquare;
  810.     rect.bottom = rect.top  + cySquare;
  811.  
  812.     FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
  813. }
  814.  
  815.  
  816. //
  817. //  FUNCTION: SetPalCtrlPalette(HWND, HPALETTE)
  818. //
  819. //  PURPOSE:  Set a palette control's hPal in its PALCTRLINFO structure.
  820. //            This sets the palette that will be displayed in the
  821. //            given window.  Also sets up the number of color entries
  822. //            field in the PALCTRLINFO structure.
  823. //
  824. //  PARAMETERS:
  825. //
  826. //    hWnd      - Window we're going to display palette in.
  827. //    hPal      - Palette to display in the window.
  828. //
  829. //  RETURN VALUE:
  830. //
  831. //    None.
  832. //
  833. //  COMMENTS:
  834. //
  835.  
  836. void SetPalCtrlPalette(HWND hWnd, HPALETTE hPal)
  837. {
  838.     HANDLE    hPalCtrlInfo;
  839.     LPPALCTRLINFO lpPalCtrlInfo;
  840.  
  841.     if (!hPal)
  842.         return;
  843.  
  844.     hPalCtrlInfo = (HANDLE)GetWindowLong(hWnd, WL_PAL_HPALCTRLINFO);
  845.  
  846.     if (hPalCtrlInfo)
  847.     {
  848.         lpPalCtrlInfo           = (LPPALCTRLINFO)GlobalLock(hPalCtrlInfo);
  849.         lpPalCtrlInfo->hPal     = hPal;
  850.         lpPalCtrlInfo->nEntries = ColorsInPalette(hPal);
  851.  
  852.         GlobalUnlock(hPalCtrlInfo);
  853.     }
  854. }
  855.